import { useEffect, useRef, useState } from "react";
import * as THREE from "three";
import "./index.less";
import { setModel } from "../../stores";

/**
 * 触摸屏控制，摇杆适配
 * radius :摇杆半径
 */
export default function JoyStick({ radius = 50 }) {
  // -------------------------------变量声明-------------------------------- //
  const [stick, setStick] = useState(false); // 摇杆是否按下
  const [joyPos, setJoyPos] = useState({ x: 0, y: 0 }); // 摇杆出现位置
  const [stickPos, setStickPos] = useState({ x: 0, y: 0 }); // 摇杆相对移动位置
  const [click, setClick] = useState(false); // 按钮是否按下

  const [isTouchScreen, setIsTouchScreen] = useState(false);

  const joyStick = useRef<HTMLDivElement>(null);
  const stickBox = useRef<HTMLDivElement>(null);
  // -------------------------------生命周期-------------------------------- //
  // 检测是否是触摸屏
  useEffect(() => {
    if ("ontouchstart" in window || navigator.maxTouchPoints > 0) {
      setIsTouchScreen(true);
    } else {
      setIsTouchScreen(false);
    }
  }, []);
  // -------------------------------响应函数-------------------------------- //
  // 获取摇杆
  function getStick(e: React.TouchEvent) {
    e.stopPropagation();
    if (stick) return;
    setJoyPos({
      x: e.touches[0].clientX - radius,
      y: e.touches[0].clientY - radius,
    });
    setStick(true);
  }
  // 释放摇杆
  function releaseStick() {
    joyStick.current?.classList.remove("appear");
    joyStick.current?.classList.add("disappear");

    resetStick();
    setTimeout(() => {
      setStick(false);
    }, 200);
  }
  // 摇杆移动
  function stickMove(e: React.TouchEvent) {
    e.stopPropagation();
    const stickPosX = e.touches[0].clientX - joyPos.x - radius;
    const stickPosY = e.touches[0].clientY - joyPos.y - radius;

    const stickPos = new THREE.Vector3(stickPosX, stickPosY); // 左右移动
    if (stickPos.length() > radius) {
      stickPos.multiplyScalar(radius / stickPos.length());
    }
    setStickPos(stickPos);
    const direction = new THREE.Vector3(stickPos.x, 0, stickPos.y);
    setModel({ director: direction });
  }

  // 复位摇杆
  function resetStick() {
    setStickPos(new THREE.Vector2(0, 0));
    setModel({ director: undefined });
  }
  // 按下按钮
  function touchStart(e: React.TouchEvent) {
    e.stopPropagation();
    setClick(true);
    setModel({ action: true });
  }
  // 松开按钮
  function touchEnd(e: React.TouchEvent) {
    e.stopPropagation();
    setClick(false);
    setModel({ action: false });
  }

  return (
    isTouchScreen && (
      <div
        className="rocker"
        onTouchStart={getStick}
        onTouchMove={stickMove}
        onTouchEnd={releaseStick}
        // style={{ pointerEvents: stick ? "none" : "painted" }}
      >
        {(stick || true) && (
          <div
            ref={joyStick}
            className="joystick appear"
            onTouchStart={getStick}
            onTouchMove={stickMove}
            onTouchEnd={releaseStick}
            style={{
              // left: joyPos.x,
              // top: joyPos.y,
              width: radius * 2 + "px",
              height: radius * 2 + "px",
            }}
          >
            <div className="stickBox">
              <div
                ref={stickBox}
                className="stick"
                style={{
                  left: stickPos.x,
                  top: stickPos.y,
                  width: radius + "px",
                  height: radius + "px",
                }}
              />
            </div>
          </div>
        )}

        <div
          className={click ? "button click" : "button"}
          style={{ width: radius + "px", height: radius + "px" }}
          onTouchStart={touchStart}
          onTouchEnd={touchEnd}
        />
      </div>
    )
  );
}
